﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace CloudPms.Common.LogProvider
{
    public class ModelBase<T> : IModelBase<T> where T : class, new()
    {
        protected ModelBase()
        {
        }

        public DbContext GetContext(string dbKey)
        {
            return new LogContext(DbConnectionProvider.GetBaseConnectionString(dbKey));
        }

        public DbContext GetContext()
        {
            return new LogContext(DbConnectionProvider.GetBaseConnectionString());
        }

        #region implemented IRepository

        public T Create()
        {
            using (DbContext context = GetContext())
            {
                return context.Set<T>().Create();
            }
        }

        public T Update(T entity)
        {
            using (DbContext context = GetContext())
            {
                context.Set<T>().Attach(entity);

                context.Entry<T>(entity).State = EntityState.Modified;

                context.SaveChanges();

            }
            return entity;
        }

        public T Insert(T entity)
        {
            //try
            //{
            using (DbContext context = GetContext())
            {
                context.Set<T>().Add(entity);
                context.Entry(entity).State = EntityState.Added;
                context.SaveChanges();
            }
            //}
            //catch (System.Data.Entity.Validation.DbEntityValidationException error)
            //{
            //    throw error;
            //}
            return entity;
        }

        public void Delete(T entity)
        {
            using (DbContext context = GetContext())
            {
                context.Set<T>().Attach(entity);
                context.Set<T>().Remove(entity);
                context.SaveChanges();
            }
        }

        public T Find(params object[] keyValues)
        {
            if (!ParamsIsValid(keyValues))
            {
                throw new ArgumentNullException("keyValues is Con't be Null");
            }

            using (DbContext context = GetContext())
            {
                return context.Set<T>().Find(keyValues);
            }
        }

        public T Find(Expression<Func<T, bool>> exp)
        {
            using (DbContext context = GetContext())
            {
                return context.Set<T>().FirstOrDefault(exp);
            }
        }

        public IList<T> FindAll()
        {
            using (DbContext context = GetContext())
            {
                return context.Set<T>().ToList();
            }

        }

        public void BatchInsert(IEnumerable<T> entities)
        {
            using (DbContext context = GetContext())
            {
                foreach (var entity in entities)
                {
                    context.Set<T>().Add(entity);

                    context.Entry(entity).State = EntityState.Added;
                }
                //try
                //{
                context.SaveChanges();
                //}catch (System.Data.Entity.Validation.DbEntityValidationException error)
                // {
                //     var xx = error;
                //}

            }
        }

        public void BatchUpdate(IEnumerable<T> entities)
        {
            using (DbContext context = GetContext())
            {
                foreach (var entity in entities)
                {
                    context.Set<T>().Attach(entity);

                    context.Entry<T>(entity).State = EntityState.Modified;
                }

                context.SaveChanges();
            }
        }

        public void BatchDelete(IEnumerable<T> entities)
        {
            using (var context = GetContext())
            {
                foreach (var entity in entities)
                {
                    context.Set<T>().Attach(entity);

                    context.Entry<T>(entity).State = EntityState.Deleted;

                    context.Set<T>().Remove(entity);
                }

                context.SaveChanges();
            }

        }

        public IList<T> BatchFind(Expression<Func<T, bool>> exp)
        {
            using (DbContext context = GetContext())
            {
                return context.Set<T>().Where(exp).ToList();
            }
        }

        #endregion

        /// <summary>
        /// 传参数据验证
        /// </summary>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public bool ParamsIsValid(object[] keyValues)
        {
            if (keyValues != null)
            {
                return keyValues.All(value => value != null);
            }
            return false;
        }


    }
}